package com.mt.family.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mt.family.common.Constants;
import com.mt.family.common.Result;
import com.mt.family.entity.DTO.RegisterDto;
import com.mt.family.entity.DTO.updateDto;
import com.mt.family.entity.Login;
import com.mt.family.entity.Menu;
import com.mt.family.entity.Validation;
import com.mt.family.exception.ServiceException;
import com.mt.family.service.LoginService;
import com.mt.family.service.MenuService;
import com.mt.family.util.EmailPhoneMatches;
import com.mt.family.util.MD5Util;
import com.mt.family.util.TokenUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 胖头鱼
 */
@RestController
@RequestMapping("/user")
public class LoginController {


    @Resource
    private LoginService loginService;

    @Resource
    private MenuService menuService;

    @PostMapping("/login")
    public Result<?> log(@RequestBody Map<String, Object> loginObj) {
        String loginName = (String) loginObj.get("loginName"); // 登录名
        String password = (String) loginObj.get("userPassword");// 登录密码
        Login userInfo = null;
        try {
            userInfo = loginService.login(loginName, password);
        } catch (Exception e) {
            throw new ServiceException(Constants.Code_500, "账号或密码错误");
        }
        Integer userTypeId = userInfo.getUserType(); // 0管理表；1学生表；2教师表
        Integer userId = userInfo.getId();// 当前用户在登录表中的标识

        Login loginUserInfo = loginService.BaseResultMap(userId, userTypeId);
        if (loginUserInfo == null) {
            throw new ServiceException(Constants.Code_600, "该用户没有登录权限");
        }
        // 生成token
        String token = TokenUtils.getToken(loginUserInfo.getId().toString(), loginUserInfo.getPassWord()); // 创建token
        loginUserInfo.setToken(token); // 返回token
        List<Menu> menus = menuService.findMenus(""); // 查询出所有的menu菜单
        //获取登录表中的用户类型
        Integer userType = loginUserInfo.getUserType();

        // 通过userType 来获取当前角色的菜单信息
        List<Integer> userMenus = menuService.selectByRoleId(userType); // 用户的菜单信息
        List<Menu> roleMenus = new ArrayList<>(); // 最后返回的角色的菜单信息
        for (Menu menu : menus) {
            if (userMenus.contains(menu.getId())) {
                roleMenus.add(menu);
            }
            List<Menu> children = menu.getChildren();
            children.removeIf(child -> !userMenus.contains(child.getId()));
            loginUserInfo.setMenuList(roleMenus);
        }
        return Result.success(loginUserInfo);
    }

    /**
     * 更新密码
     *
     * @param passObj
     * @return
     */
    @PutMapping("/updatePass")
    private Result<?> updatePass(@RequestBody Map<String, Object> passObj) {
        Integer currentUserId = (Integer) passObj.get("currentUserId"); // 当前登录用户id
        String oldPassword = (String) passObj.get("oldPassword");// 旧密码
        String newPassword = (String) passObj.get("newPassword"); // 新密码
        System.out.println(currentUserId + "," + oldPassword + "," + newPassword);

        boolean ifNull = loginService.updatePassWord(currentUserId, oldPassword, newPassword);// 判断密码是否正确

        return Result.success(ifNull);
    }


    /**
     * 更新用户基本信息操作。
     * 1、需要更新用户表和登录表
     * 2、如何找到对应的表：
     * 1）通过userTypeId 来觉得是管理员表还是学生表还是教师表
     * 2）通过log_id 来决定更新的是那个用户
     *
     * @param updateObj
     * @param userTypeById
     * @return
     */
    @PutMapping("/updateInfo/{userTypeById}")
    public Result<?> updateInfo(@RequestBody updateDto updateObj, @PathVariable Integer userTypeById) {

        boolean phoneJudge = EmailPhoneMatches.judgePhone(updateObj.getPhone());
        boolean emailJudge = EmailPhoneMatches.judgeEmail(updateObj.getEmail());
        if (!emailJudge) {
            throw new ServiceException(Constants.Code_403, "邮箱格式错误!");
        }
        if (!phoneJudge) {
            throw new ServiceException(Constants.Code_403, "手机号格式错误!");
        }
        boolean userInfo = loginService.updateUserInfo(updateObj, userTypeById);
        return Result.success();
    }

    /**
     * 获得登录表中的信息
     */
    @GetMapping("/info")
    public Result<?> getLoginInfo(@RequestParam(defaultValue = "1") Integer pageNum,
                                  @RequestParam(defaultValue = "5") Integer pageSize,
                                  @RequestParam(defaultValue = "") String searchEnable,
                                  @RequestParam(defaultValue = "") String searchUserType,
                                  @RequestParam(defaultValue = "") String searchLoginNo) {
        Page<Login> pageLogInfo = loginService.returnLogInfo(pageNum, pageSize, searchEnable, searchUserType, searchLoginNo);
        return Result.success(pageLogInfo);
    }

    @PutMapping("/setEnable/{enable}/{userId}")
    public Result<?> setEnable(@PathVariable Integer enable, @PathVariable Integer userId) {
        System.out.println(TokenUtils.getCurrentUser().getId());
        if (userId.equals(Objects.requireNonNull(TokenUtils.getCurrentUser()).getId())) {
            throw new ServiceException(Constants.Code_500, "当前账号正在被你使用，不能操作");
        }
        UpdateWrapper<Login> loginUpdateWrapper = new UpdateWrapper<>();
        loginUpdateWrapper.set("enable", enable);
        boolean update = loginService.update(loginUpdateWrapper);
        if (!update) {
            return Result.error(Constants.Code_500, "修改失败");
        }
        return Result.success(update);
    }

    /**
     * 批量删除功能
     */
    @PostMapping("/del")
    public Result<?> delUserByIds(@RequestBody List<Integer> userIds) {
        boolean isTrue = loginService.removeUsers(userIds);
        return Result.success(isTrue);
    }

    /**
     * 单个删除功能
     */
    @PostMapping("/delUser/{userId}/{userTypeId}")
    public Result<?> delUserById(@PathVariable Integer userId, @PathVariable Integer userTypeId) {

        // 和当前用户id做比较
        if (userId.equals(Objects.requireNonNull(TokenUtils.getCurrentUser()).getId())) {
            throw new ServiceException(Constants.Code_500, "当前账号正在被你使用，无法删除");
        }
        boolean removeUserById = loginService.removeUserById(userId, userTypeId);
        if (removeUserById) {
            return Result.success();
        }
        throw new ServiceException(Constants.Code_500, "删除指定用户失败");
    }

    @PutMapping("/reset/{currentUserId}")
    public Result<?> resetPass(@PathVariable Integer currentUserId, @RequestBody String userType) {
        UpdateWrapper<Login> loginUpdateWrapper = new UpdateWrapper<>();
        String managePass = MD5Util.getMD5("123456");
        String teaPass = MD5Util.getMD5("999999");
        String stuPass = MD5Util.getMD5("666666");
        System.out.println(userType);
        if ("管理员".equals(userType)) { // 管理
            loginUpdateWrapper.eq("id", currentUserId).set("pass_word", managePass);
        } else if ("学生".equals(userType)) { // 学生
            loginUpdateWrapper.eq("id", currentUserId).set("pass_word", stuPass);
        } else if ("教师".equals(userType)) { // 教师
            loginUpdateWrapper.eq("id", currentUserId).set("pass_word", teaPass);
        }
        boolean update = loginService.update(loginUpdateWrapper);
        return Result.success(update);
    }

    /**
     * 添加用户
     */

    @PostMapping("/add")
    public Result<?> addUser(@RequestBody RegisterDto register) {
        String emailVer = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
        String phone = "^1[3-9]\\d{9}$";
        if (!register.getEmail().matches(emailVer)) {
            throw new ServiceException(Constants.Code_403, "邮箱格式错误");
        }
        if (!register.getPhone().matches(phone)) {
            throw new ServiceException(Constants.Code_403, "手机号格式错误");
        }
        boolean user = loginService.registerUser(register);

        return Result.success(user);
    }

    /**
     * 发送邮箱验证码
     */
    @PostMapping("/email/{email}/{type}")
    public Result<?> sendEmail(@PathVariable String email, @PathVariable Integer type) {
        // 发送验证码之前，查询，这个邮箱是不是 系统用户中的邮箱
        QueryWrapper<Login> loginQueryWrapper = new QueryWrapper<>();
        loginQueryWrapper.eq("email", email);
        Login haveLogin = loginService.getOne(loginQueryWrapper);
        if (haveLogin == null) {
            throw new ServiceException(Constants.Code_500, "不存在此用户");
        }
        loginService.sendEmail(email, type);
        return Result.success();
    }

    /**
     * 邮箱登录
     */
    @PostMapping("/email/login")
    public Result<?> loginEmail(@RequestBody Validation validation) {
        Login login = loginService.loginEmail(validation);
        return Result.success(login);
    }

    /**
     * 邮箱登录
     */
    @PostMapping("/email/code")
    public Result<?> matchCode(@RequestBody Validation validation) {
        loginService.matchCode(validation);
        return Result.success();
    }
    /**
     * 重置密码
     */
    @PostMapping("/email/resetPassword")
    public Result<?> resetPassword(@RequestBody Map<String ,Object> obj){

        String password = (String) obj.get("password");
        String email = (String) obj.get("email");

        String newPassWord = MD5Util.getMD5(password);
        QueryWrapper<Login> loginQueryWrapper = new QueryWrapper<>();
        loginQueryWrapper.eq("email",email);
        Login login = loginService.getOne(loginQueryWrapper);
        if (login == null) {
            throw new ServiceException(Constants.Code_500,"用户不存在");
        }
        UpdateWrapper<Login> loginUpdateWrapper = new UpdateWrapper<>();
        loginUpdateWrapper.set("pass_word",newPassWord).eq("email",email);
        loginService.update(loginUpdateWrapper);
        return Result.success();
    }
}


